package com.neusoft.neuiotms.dcom.service.alter.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.persistence.EntityNotFoundException;
import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.activiti.service.ProcessInstanceService;
import com.neusoft.bizcore.auth.common.bean.UserBean;
import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.neuiotms.dcom.constants.DCOMConstants;
import com.neusoft.neuiotms.dcom.converter.alter.AlterSecondLineConverter;
import com.neusoft.neuiotms.dcom.dto.alter.AlterSecondLineDTO;
import com.neusoft.neuiotms.dcom.model.alter.AlterSecondLine;
import com.neusoft.neuiotms.dcom.repository.alter.AlterSecondLineRepository;
import com.neusoft.neuiotms.dcom.service.alter.AlterSecondLineService;
import com.neusoft.neuiotms.micro.auth.AuthMicroService;
import com.neusoft.neuiotms.micro.dcam.DcamMicroService;

@Service
public class AlterSecondLineServiceImpl implements AlterSecondLineService {

    @Autowired
    private ProcessInstanceService processInstanceService;
    @Autowired
    private AlterSecondLineConverter alterSecondLineConverter;
    @Autowired
    private AlterSecondLineRepository alterSecondLineRepository;
    @Autowired
    private AuthMicroService authMicroService;
    @Autowired
    private DcamMicroService dcamMicroService;

    @Transactional
    @Override
    public AlterSecondLineDTO create(final AlterSecondLineDTO dto, final String type, final UserBean user) {
        // 设置当前节点操作人
        dto.setOperatorCode(user.getUsername());
        dto.setOperatorName(user.getName());

        if ("before".equals(type)) {
            // 设置是否转派转二线的流程变量
            this.processInstanceService.setGlobalVariable(dto.getTaskId(),
                    DCOMConstants.ALTER_PROCESS_SECOND_LINE_WHETHER_TRANSFER, dto.isTransfer());

        }

        // 判断是否转二线
        if (dto.isTransfer()) {
            // 设置二线人员的审批人和名称
            this.processInstanceService.setGlobalVariable(dto.getTaskId(),
                    DCOMConstants.ALTER_PROCESS_EXECUTOR_TRANSFER_SECOND_OPERATOR_CODE,
                    dto.getTransferEngineerCode());
            this.processInstanceService.setGlobalVariable(dto.getTaskId(),
                    DCOMConstants.ALTER_PROCESS_EXECUTOR_TRANSFER_SECOND_OPERATOR_NAME,
                    dto.getTransferEngineerName());
        }

        // 设置会签节点的人员集合
        final List<String> dispatchUserList = new ArrayList<>();
        final Object teamLeader = this.processInstanceService.getVariables(dto.getWorkNum(),
                DCOMConstants.ALTER_PROCESS_EXECUTOR_OPERATION_TEAMLEADER, null);
        if (null != teamLeader) {
            dispatchUserList.add(teamLeader.toString());
        }
        // 查询领导
        final Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("s_roleCode", "zongjian");
        final List<Map<String, Object>> leaderList = this.authMicroService.userIndex(queryMap).getData();
        leaderList.stream().forEach(e -> {
            dispatchUserList.add(e.get("username").toString());
        });
        this.processInstanceService.setGlobalVariable(dto.getTaskId(), "dispatchUserList",
                dispatchUserList.stream().distinct().collect(Collectors.toList()));

        // 完成节点
        this.processInstanceService.complete(dto.getWorkNum(), dto.getTaskId(), user);

        // 保存操作信息
        final AlterSecondLine model = this.alterSecondLineConverter.toModel(dto);
        this.alterSecondLineRepository.save(model);
        return this.alterSecondLineConverter.toDTO(model);
    }

    @Override
    public AlterSecondLineDTO detail(final String workNum, final String taskId, final UserBean user) {
        AlterSecondLine model = null;
        try {
            if (StringUtils.isNotBlank(workNum) && !DCOMConstants.STR_NULL.equals(taskId)) {
                model = this.alterSecondLineRepository.findByWorkNumAndTaskId(workNum, taskId);
                if (model == null) {
                    // 获取前一节点的TaskID
                    final String fromProcessTaskId = this.processInstanceService.getLastTaskId(taskId, user);
                    if (fromProcessTaskId == null) {
                        final AlterSecondLineDTO dto = new AlterSecondLineDTO();
                        // 从流程变量里面取当前是否转派过来的
                        final Object transfer = this.processInstanceService.getVariables(workNum,
                                DCOMConstants.ALTER_PROCESS_SECOND_LINE_WHETHER_TRANSFER, null);

                        if ((transfer != null) && (transfer instanceof Boolean)) {
                            dto.setTransfer((Boolean) transfer);
                            dto.setTransferUserName(user.getName());
                        }

                        // 查询备品备件信息
                        dto.setSpareParts(this.dcamMicroService
                                .searchFinishStockListByWorknumAndConfirmUser(workNum, user.getUsername()).getData());
                        return dto;
                    } else {
                        model = this.alterSecondLineRepository.findByWorkNumAndTaskId(workNum, fromProcessTaskId);
                    }
                }
            } else if (DCOMConstants.STR_NULL.equals(taskId)) {
                model = this.alterSecondLineRepository.findTopByWorkNumOrderByIdDesc(workNum);
            }
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND,
                    new Object[] {workNum },
                    new Object[] {taskId });
        }

        // 设置谁转派的
        final AlterSecondLineDTO dto = this.alterSecondLineConverter.toDTO(model);
        dto.setTransferUserName(model.getOperatorName());

        // 查询备品备件信息
        dto.setSpareParts(this.dcamMicroService
                .searchFinishStockListByWorknumAndConfirmUser(workNum, dto.getOperatorCode()).getData());
        return dto;
    }

}
